﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using TireService.Data;
using DevExpress.Web.ASPxCallback;
using DevExpress.Web.ASPxEditors;
using System.Web.Security;
using System.Configuration;

namespace TireService.Website.Integration
{
    public partial class Opret : System.Web.UI.Page
    {
        //private int _customerid;
        //private int _carnumber;
        //private int _carcount;
        //private int _subscriptionid;
        private string _primaryaddress;
        private string _secondaryaddress;

        //public int CustomerId
        //{
        //    get
        //    {
        //        return this._customerid;
        //    }
        //    set
        //    {
        //        this._customerid = value;
        //    }
        //}

        //public int CarNumber
        //{
        //    get
        //    {
        //        return this._carnumber;
        //    }
        //    set
        //    {
        //        this._carnumber = value;
        //    }
        //}

        //public int CarCount
        //{
        //    get
        //    {
        //        return this._carcount;
        //    }
        //    set
        //    {
        //        this._carcount = value;
        //    }
        //}

        //public int SubscriptionId
        //{
        //    get
        //    {
        //        return this._subscriptionid;
        //    }
        //    set
        //    {
        //        this._subscriptionid = value;
        //    }
        //}

        public string PrimaryAddress
        {
            get
            {
                return this._primaryaddress;
            }
            set
            {
                this._primaryaddress = value;
            }
        }

        public string SecondaryAddress
        {
            get
            {
                return this._secondaryaddress;
            }
            set
            {
                this._secondaryaddress = value;
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (Page.IsPostBack != true)
            {
                try
                {
                    int CustomerId = Convert.ToInt32(Request.QueryString["cid"]);

                    // Instantiate datalayer
                    TireServiceDB db = new TireServiceDB();

                    // Fetch customer
                    Customer customer = db.GetCustomer(CustomerId);

                    if (customer == null)
                    {
                        // Raise exception
                    }
                    else
                    {
                        this.PrimaryAddress = customer.Address + "|" + customer.ZipCode + "|" + customer.City;
                        this.SecondaryAddress = customer.SecondaryAddress + "|" + customer.SecondaryZipCode + "|" + customer.SecondaryCity;

                        PrepareCarInfoForm(db, customer.CustomerId);
                    }
                }
                catch (Exception ex)
                {
                    // TODO: Handle error
                }
                
            }

            // Steps

            // 1: Get customerid from querystring
            // 2: Read number of cars for creation (OLD)
            // 3: Show signup for (use, usercontrol for adding cars) (OLD)
            // 4: Create cars, tireset
            // 5. Create user
            // 6: Send login detail mail
            // 7: mark externalinterface with finalise date
            // 8: Redirect customer to online booking / mysite


        }

        public void PrepareCarInfoForm(TireServiceDB db, int CustomerId) 
        {
            List<CustomerSubscription> customersubscriptions = db.GetCustomerSubscriptions(CustomerId);

            bool loadcar = false;

            foreach (CustomerSubscription customersubscription in customersubscriptions)
            {
                // Check if something is already loaded
                if (!loadcar)
                {
                    List<Car> car = db.GetCarByCustomerSubscriptionId(customersubscription.CustomerSubscriptionId);

                    if (car.Count != 0)
                    {
                        // Cars already exists - remove subscription in list
                        customersubscriptions.Remove(customersubscription);
                    }
                    else
                    {
                        // Indicate that car is loaded
                        loadcar = true;

                        LoadCarInfoFrom(db, customersubscription, customersubscriptions.Count());
                    }
                }
                
            }

            if (!loadcar)
            {
                // No car was loaded - meaning all cars is created, redirect user to login
                Response.Redirect("~/Login.aspx");
            }

            // Store list of customer subscriptions
            Session["CustomerSubscriptionList"] = customersubscriptions;

        }

        public void LoadCarInfoFrom(TireServiceDB db, CustomerSubscription customersubscription, int CarCount) 
        {
            hfCustomerSubscriptionId["CustomerSubscriptionId"] = customersubscription.CustomerSubscriptionId.ToString();

            lblCarCount.Text = CarCount + " biler mangler - indtast for næste bil nedenfor";

            lblSubscriptionDescription.Text = db.GetSubscriptionDescription(customersubscription.SubscriptionId);
            lblSubscriptionId.Text = customersubscription.SubscriptionId.ToString();

            // Get data for car brand dropdownlist
            ddlCarBrand.DataSource = db.GetCarBrand();
            ddlCarBrand.ValueField = "CarBrandId";
            ddlCarBrand.TextField = "Description";
            ddlCarBrand.DataBind();

            int TodayYear = DateTime.Now.Year;

            for (int i = TodayYear; i > 1990; i--)
            {
                ListEditItem item = new ListEditItem();
                item.Value = i;
                item.Text = i.ToString();
                txtYear.Items.Add(item);
            }

            // Show possible adresses to select from if tireset should be returned
            ddlSelectAddress.Items.Clear();
            string add1 = this.PrimaryAddress;
            string add2 = this.SecondaryAddress;
            string add3 = "-- Anden adresse --";

            ddlSelectAddress.Items.Add(add1, 0);
            ddlSelectAddress.Items.Add(add2, 1);
            ddlSelectAddress.Items.Add(add3, 2);

            // Clear form
            txtRegistrationNumber.Text = "";
            ddlCarBrand.SelectedIndex = -1;
            txtModel.Text = "";
            txtEngineSize.Text = "";
            ddlFuelType.SelectedIndex = -1;
            ddlOtherTireSet.SelectedIndex = -1;
            ddlSelectAddress.SelectedIndex = -1;
            rblCurrentTireSet.SelectedIndex = -1;
            cbLockingBolt.Checked = false;
            cbLockingOtherTireSet.Checked = false;
            txtPickUpCustomerTireSetAddress.Text = "";
            txtPickUpCustomerTireSetZipCode.Text = "";
            txtPickUpCustomerTireSetCity.Text = "";
            txtPickUpCustomerTireSetRemarkToAddress.Text = "";
            txtColor.Text = "";
            txtYear.SelectedIndex = -1;
        }

        /// <summary>
        /// Callback function that add car
        /// </summary>
        protected void callBackAddCar_Callback(object source, DevExpress.Web.ASPxClasses.CallbackEventArgsBase e)
        {
            try
            {
                // Get values from client
                // 0: Registrationnumber
                // 1: Car brand id
                // 2: Car model
                // 3: Enginesize
                // 4: Fueltype
                // 5: Year
                // 6: Color
                // 7: Currenttireset (0: Winter, 1: Summer)
                // 8: Locking bolts on current tireset (true/false)
                // 9: Othertireset (0: Get on first service, 1: Pick-up, 2: MBH has customer tires)
                // 10: Locking bolts on other tireset (true/false)
                // 11: Pickup address (optional)
                // 12: Pickup zipcode (optional)
                // 13: Pickup city (optional)
                // 14: Remarks to pickup address (optional)
                // 15: SubscriptionId
                // 16: CustomerSubscriptionId
                string[] param = e.Parameter.Split('|');

                // Instantiate datalayer
                TireServiceDB db = new TireServiceDB();

                // Define system userid (Used for logging)
                Guid SystemUserId = new Guid(ConfigurationManager.AppSettings["SystemUserId"].ToString()); // System ID - Jannik79

                // Prepare email service
                EmailNotificationServices emailService = new EmailNotificationServices();

                // Initiate customer subscription business logic
                CustomerSubscriptionBLL customersubscriptionBLL = new CustomerSubscriptionBLL();

                // Instantiate task business logic layer
                TaskBLL taskBLL = new TaskBLL();

                // Instantiate tireset and container business logic
                TireSetBLL tiresetBLL = new TireSetBLL();
                ContainerCargoRoomBLL containerBLL = new ContainerCargoRoomBLL();

                // Instantiate tiresetlog business logic
                TireSetLogBLL tiresetlogBLL = new TireSetLogBLL();

                // Get customersubscription
                CustomerSubscription customersubscription = db.GetCustomerSubscription(Convert.ToInt32(param[16]));

                // Get customer
                Customer customer = db.GetCustomer(customersubscription.CustomerId);

                // Store values to car
                int CustomerSubscriptionId = Convert.ToInt32(param[16]);
                string RegistrationNumber = param[0].ToString();
                int CarBrandId = Convert.ToInt32(param[1]);
                string Model = param[2].ToString();
                string EngineSize = param[3].ToString();
                int FuelType = Convert.ToInt32(param[4]);
                int Year = Convert.ToInt32(param[5]);
                string Color = param[6].ToString();
                int CurrentTireset = Convert.ToInt32(param[7]);
                bool CurrentTiresetLockingbolts = Convert.ToBoolean(param[8]);
                int OtherTireSetAction = Convert.ToInt32(param[9]); // 0: We will get tires on first service, 1: Pickup tires, 2: We have the tires
                bool OtherTiresetLockingbolts = Convert.ToBoolean(param[10]);
                string PickupAddress = param[11].ToString();
                string PickupZipCode = param[12].ToString();
                string PickupCity = param[13].ToString();
                string RemarksToPickupAddress = param[14].ToString();
                int SubscriptionId = Convert.ToInt32(param[15]);

                // Create new car
                Car car = new Car();
                car.CustomerId = customersubscription.CustomerId;
                car.CustomerSubscriptionId = customersubscription.CustomerSubscriptionId;
                car.RegistrationNumber = RegistrationNumber;
                car.CarBrandId = CarBrandId;
                car.Model = Model;
                car.EngineSize = EngineSize;
                car.FuelType = FuelType;
                car.Year = Year;
                car.Color = Color;
                car.CarStatusId = (int)Shared.CarStatus.NeedsTireChanged;

                db.AddCar(car);

                // Placeholder for adding new tires to new car
                TireSet tireset1 = new TireSet();
                TireSet tireset2 = new TireSet();

                // Prepare tasks
                Task servicetask = new Task();
                Task pickuptask = new Task();

                // Add tiresets for new car

                // Determine what tires are on the car
                int tireset1status, tireset2status;
                int? tireset1container, tireset2container;
                bool tireset1lockingbolt, tireset2lockingbolt;

                int tiresetonstockstatus = (int)Shared.TireSetStatus.OnStock;

                if (OtherTireSetAction == 0)
                {
                    // Customer has tireset
                    tiresetonstockstatus = (int)Shared.TireSetStatus.PlacedAtCustomer;
                }
                if (OtherTireSetAction == 1)
                {
                    // Tirest should be picked up - create task
                    tiresetonstockstatus = (int)Shared.TireSetStatus.PlacedAtCustomer;

                    // Create pickup tireset (Will happen furtherdown in code when tireset is created)
                }
                if (OtherTireSetAction == 2)
                {
                    // We already have the tireset
                    tiresetonstockstatus = (int)Shared.TireSetStatus.OnStock;

                    // TODO: Make code for selecting right container
                }

                // Check current tires on car
                if (CurrentTireset == 0)
                {
                    // Winter tires on car
                    tireset1status = tiresetonstockstatus;
                    tireset1container = containerBLL.ReturnNearestContainerCargoRoomId(db, float.Parse(customer.LatitudePrimary.ToString()), float.Parse(customer.LongitudePrimary.ToString()));
                    tireset1lockingbolt = OtherTiresetLockingbolts;
                    tireset2status = (int)Shared.TireSetStatus.MountedOnCar;
                    tireset2container = null;
                    tireset2lockingbolt = CurrentTiresetLockingbolts;
                }
                else
                {
                    // Summer tires on car
                    tireset1status = (int)Shared.TireSetStatus.MountedOnCar;
                    tireset1container = null;
                    tireset1lockingbolt = CurrentTiresetLockingbolts; ;
                    tireset2status = tiresetonstockstatus;
                    tireset2container = containerBLL.ReturnNearestContainerCargoRoomId(db, float.Parse(customer.LatitudePrimary.ToString()), float.Parse(customer.LongitudePrimary.ToString()));
                    tireset2lockingbolt = OtherTiresetLockingbolts;
                }

                tiresetBLL.UpdateTireSet(
                                    db,
                                    tireset1,
                                    car,
                                    (int)Shared.TireType.SummerTires,
                                    null,
                                    null,
                                    null,
                                    null,
                                    null,
                                    null,
                                    null,
                                    tireset1lockingbolt,
                                    false,
                                    false,
                                    false,
                                    false,
                                    null,
                                    null,
                                    tireset1status,
                                    null,
                                    tireset1container,
                                    true,
                                    false,
                                    null,
                                    SystemUserId,
                                    null,
                                    true
                                );

                tiresetBLL.UpdateTireSet(
                                    db,
                                    tireset2,
                                    car,
                                    (int)Shared.TireType.WinterTires,
                                    null,
                                    null,
                                    null,
                                    null,
                                    null,
                                    null,
                                    null,
                                    tireset2lockingbolt,
                                    false,
                                    false,
                                    false,
                                    false,
                                    null,
                                    null,
                                    tireset2status,
                                    null,
                                    tireset2container,
                                    true,
                                    false,
                                    null,
                                    SystemUserId,
                                    null,
                                    true
                                );

                // Check if tireset should be picked-up, if yes: create task
                if (OtherTireSetAction == 1)
                {
                    if (tireset1.TireSetStatusId != (int)Shared.TireSetStatus.MountedOnCar)
                    {
                        // Create servicedrive task
                        pickuptask = taskBLL.CreateTask(db,
                                                    null,
                                                    (int)Shared.TaskType.ServiceDrive,
                                                    (int)Shared.TaskDetailType.ServiceDrive_PickUpTire,
                                                    (int)Shared.TaskTypeStatus.ServiceDrive_Created,
                                                    customer,
                                                    car,
                                                    tireset1,
                                                    PickupAddress,
                                                    PickupZipCode,
                                                    PickupCity,
                                                    0,
                                                    RemarksToPickupAddress,
                                                    PickupAddress,
                                                    PickupZipCode,
                                                    PickupCity,
                                                    0,
                                                    RemarksToPickupAddress,
                                                    "Ny kunde",
                                                    1,
                                                    SystemUserId,
                                                    true);
                    }
                    else
                    {
                        // Create servicedrive task
                        pickuptask = taskBLL.CreateTask(db,
                                                    null,
                                                    (int)Shared.TaskType.ServiceDrive,
                                                    (int)Shared.TaskDetailType.ServiceDrive_PickUpTire,
                                                    (int)Shared.TaskTypeStatus.ServiceDrive_Created,
                                                    customer,
                                                    car,
                                                    tireset2,
                                                    PickupAddress,
                                                    PickupZipCode,
                                                    PickupCity,
                                                    0,
                                                    RemarksToPickupAddress,
                                                    PickupAddress,
                                                    PickupZipCode,
                                                    PickupCity,
                                                    0,
                                                    RemarksToPickupAddress,
                                                    "Ny kunde",
                                                    1,
                                                    SystemUserId,
                                                    true);
                    }
                }

                // Create service drive task
                if (tireset1.TireSetStatusId != (int)Shared.TireSetStatus.MountedOnCar)
                {
                    servicetask = taskBLL.CreateTask(db,
                                                null,
                                                (int)Shared.TaskType.ServiceDrive,
                                                (int)Shared.TaskDetailType.ServiceDrive_ChangeTire,
                                                (int)Shared.TaskTypeStatus.ServiceDrive_Created,
                                                customer,
                                                car,
                                                tireset1,
                                                customer.Address,
                                                customer.ZipCode,
                                                customer.City,
                                                0,
                                                null,
                                                customer.SecondaryAddress,
                                                customer.SecondaryZipCode,
                                                customer.SecondaryCity,
                                                0,
                                                null,
                                                "Ny kunde",
                                                1,
                                                SystemUserId,
                                                true);
                }
                else
                {
                    servicetask = taskBLL.CreateTask(db,
                                                null,
                                                (int)Shared.TaskType.ServiceDrive,
                                                (int)Shared.TaskDetailType.ServiceDrive_ChangeTire,
                                                (int)Shared.TaskTypeStatus.ServiceDrive_Created,
                                                customer,
                                                car,
                                                tireset2,
                                                customer.Address,
                                                customer.ZipCode,
                                                customer.City,
                                                0,
                                                null,
                                                customer.SecondaryAddress,
                                                customer.SecondaryZipCode,
                                                customer.SecondaryCity,
                                                0,
                                                null,
                                                "Ny kunde",
                                                1,
                                                SystemUserId,
                                                true);
                }

                // Check if dependency between tirepick and servicetask needs to be made
                if (OtherTireSetAction == 1)
                {
                    taskBLL.AddDependencyToTask(db, pickuptask, servicetask);
                }

                // Update car status
                car.CarStatusId = (int)Shared.CarStatus.AwaitsTireChangePlanning;

                // Update ExternalInterface - fill out finalise date if all quantities is registered
                List<ExternalOrderInterface> InterfaceOpenOrders = db.GetExternalOpenOrdersByCustomerAndSubscription(customer.CustomerId, customersubscription.SubscriptionId);

                ExternalOrderInterface order = InterfaceOpenOrders.Single();

                order.RegisteredQuantity += 1;

                if (order.RegisteredQuantity == order.Quantity)
                {
                    order.Finalisedate = DateTime.Now;    
                }
                
                db.SubmitChanges();

                // Check if user login should be created
                if (customer.UserId == null)
                {
                    try
                    {
                        // Create user
                        MembershipUser user = Membership.CreateUser(customer.Email, customer.Phone1.ToString(), customer.Email);

                        // Add user to customer role
                        Roles.AddUserToRole(user.UserName, "Kunde");

                        customer.UserId = new Guid(user.ProviderUserKey.ToString());

                        db.SubmitChanges();

                        // Send email to user with user information
                        emailService.Customer_UserInformation_SendCustomerEmail(customer.Email, customer.Name, user.UserName, customer.Phone1.ToString(), customer.CustomerId);
                    }
                    catch (Exception ex)
                    {
                        // Nothing, but error does not stop signup process for customer

                        // Send email to mobil hjulskift with error
                        string emailaddress = Convert.ToString(ConfigurationManager.AppSettings["EmailAddress"]);
                        bool test = Convert.ToBoolean(Convert.ToByte(ConfigurationManager.AppSettings["TestEnvironmentOn"]));
                        string message = String.Format("Systemet fejlede ved forsøg på at oprette kunde login - External interface<br><br>Email: {0}<br><br>Fejl: {1}", customer.Email, ex.Message);


                        Shared emailBLL = new Shared();
                        emailBLL.SendEmail(emailaddress, emailaddress, message, "Fejl ved oprettelse af brugerlogin", true, test, null, null, null);
                    }
                }

                // Check if invoicing is needed
                if (OtherTireSetAction == 1)
                {
                    // Initiate E-conomic interface
                    EconomicInterface ecoInterface = new EconomicInterface();

                    // Create orderline for invoicing
                    List<EconomicInterface.EcoOrderLine> orderlines = new List<EconomicInterface.EcoOrderLine>();

                    // Invoicing for tirepick up
                    EconomicInterface.EcoOrderLine orderline_tirepickup = new EconomicInterface.EcoOrderLine();
                    orderline_tirepickup.ProductNumber = 3; // TODO: Make more dynamic
                    orderline_tirepickup.Description = "Afhentning af hjul for bil: " + car.RegistrationNumber + " (" + PickupAddress + ", " + PickupZipCode + " " + PickupCity + ")";
                    orderline_tirepickup.Quantity = 1;
                    orderline_tirepickup.UnitPrice = 200; // TODO: Make more dynamic

                    orderlines.Add(orderline_tirepickup);

                    // Create invoice in e-conomic
                    string invoiceid = ecoInterface.CreateInvoice(db, customer.CustomerId, orderlines, true);

                    // Send email with order confirmation to customer
                    string BookingLink = Convert.ToString(ConfigurationManager.AppSettings["BookingURL"]) + "?uid=" + customer.UserId.ToString();
                    emailService.Customer_OrderConfirmationAndInvoice_SendCustomerEmail(customer.CustomerId, customer.Email, customer.Name, invoiceid, ecoInterface.GetInvoice(Convert.ToInt32(invoiceid)), "Faktura" + invoiceid + ".pdf", Convert.ToString((int)Shared.PaymentGateWayActions.InitiatePayment), Convert.ToString(ConfigurationManager.AppSettings["AcceptURL"]), BookingLink);
                }

                // Prepare / reload car input form
                PrepareCarInfoForm(db, customer.CustomerId);
            }
            catch (Exception ex)
            {
                // Error
                throw new ArgumentException(ex.Message);
            }
        }   
    }
}